package com.yhy.job.utils;

import com.yhy.common.service.RedisLock;
import com.yhy.common.utils.*;
import com.yhy.job.service.QuartzJobService;
import com.yhy.job.vo.QuartzJobVO;
import com.yhy.job.vo.mng.QuartzJobMngVO;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

/*
 *
 *  * *
 *  *  * <br>
 *  *  * <b>功能：</b><br>
 *  *  * <b>作者：</b>yanghuiyaun<br>
 *  *  * <b>日期：</b> 19-8-16 下午3:20 <br>
 *  *  * <b>版权所有：<b>版权所有(C) 2019<br>
 *  *
 *
 */
@Async
public class ExecutionJob extends QuartzJobBean {

    private Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    private final static ThreadPoolExecutor executor = ThreadPoolExecUtil.getThreadPoll("YHY-JOB");

    @Autowired
    private QuartzJobService quartzJobService;

    @Override
    protected void executeInternal(JobExecutionContext context) {
        QuartzJobMngVO quartzJob = (QuartzJobMngVO) context.getMergedJobDataMap().get(QuartzJobVO.JOB_KEY);
        RedisLock redisLock = new RedisLock(quartzJob.getId(),5000L);

        try {
            if(!redisLock.lock()) {
                LOGGER.info("任务加锁失败,正在执行，任务名称：{}", quartzJob.getJobName());
                return;
            }
            if(quartzJob.getRunning()) {
                LOGGER.info("任务正在执行，任务名称：{}", quartzJob.getJobName());
                return;
            }

            // 执行任务
            quartzJob.setRunning(true);

            boolean result = TransationExecuteContext.getTransationExecuteContext().execute(new ITransationExecutor<Boolean, String>() {
                @Override
                public Boolean execute(String param) {
                    quartzJobService.updateRunStatus(JsonUtils.tranObject(quartzJob,QuartzJobVO.class));
                    //quartzJobService.update(JsonUtils.tranObject(quartzJob,QuartzJobVO.class));
                    LOGGER.info("任务更改状态为Running，任务名称：{}", quartzJob.getJobName());
                    return true;
                }
            }, null);

            long startTime = System.currentTimeMillis();
            LOGGER.info("任务准备执行，任务名称：{}", quartzJob.getJobName());

            BaseJob baseJob = SpringContextHolder.getBean(quartzJob.getBeanName());
            baseJob.setMethodParam(quartzJob.getMethodParam());

            Future<?> future = executor.submit(baseJob);
            future.get();
            long times = System.currentTimeMillis() - startTime;
            LOGGER.info("任务执行完毕，任务名称：{} 总共耗时：{} 毫秒", quartzJob.getJobName(), times);

        } catch (Exception e) {
            LOGGER.error("任务执行失败，任务名称：{}" + quartzJob.getJobName(), e);
        } finally {
            quartzJob.setRunning(false);
            boolean result = TransationExecuteContext.getTransationExecuteContext().execute(new ITransationExecutor<Boolean, String>() {
                @Override
                public Boolean execute(String param) {
                    quartzJobService.updateRunStatus(JsonUtils.tranObject(quartzJob,QuartzJobVO.class));
                    //quartzJobService.update(JsonUtils.tranObject(quartzJob,QuartzJobVO.class));
                    LOGGER.info("任务更改状态为Runned,任务名称：{}", quartzJob.getJobName());
                    return true;
                }
            },null);
            redisLock.unlock();
        }

    }

}
